/*
 * Classe de manipulação de caracteres, aplicando codificação de Fibonacci
 *
 */
package codec.fibonacci;

import java.util.BitSet;

/**
 *
 * @author Douglas
 */
public class CodificadorFibonacci extends Fibonacci{
// Auxiliar para manipulação da variável de representação numérica do caracter
    private char intBitSetAux;

    private int aux;

    public CodificadorFibonacci(){
    }

// Cria um array de bits com representação binária do caracter principal com a 
// Sequencia de Fibonacci    
    public BitSet MontaBitSet(){
        int numeroIn = super.getCaracter();
        super.setBitSet(null);
        for(int a=12; a >= 0 ; a--){
            if (SEQFIBO[a] <= numeroIn){
                if (bitSet == null){
                    bitSet = new BitSet(a+2);
                    bitSet.set(a+1);
                }
                bitSet.set(a);
                numeroIn = numeroIn - SEQFIBO[a];
            }
        }
        return bitSet;
    }
/**
 * Aplica Codificação Fibonacci.
 * Este é o método principal, a partir do array de bits, cria uma palavra
 * respeitando a codificação fibonacci. Inicializa o número com HIGH-VALUE,
 * Percorre 16 bits do INT, pois o codificador trabalha na UTF-8. Começa
 * no MSB, para cada iteração, subtrai o valor correspondente ao bit, se assim
 * for necessário.
 *  
 * @return
 * Boolean, indicando se terminou de codificar 16 bits, pois precisa no mínimo
 * 2 bytes para gravar no arquivo
 */
    public boolean bitSetToInt(){
        boolean testInt = false;
        if (numeroBits == 0) {
            numeroBits = 16;
            intBitSet = (char)((char)Math.pow(2,numeroBits) - 1); // receber INT
            aux = intBitSet;
        }
        for(int a=0; a < bitSet.length(); a++){
            numeroBits--;
            if (!bitSet.get(a)){
                intBitSet -= (char)Math.pow(2,numeroBits);
            }
            if(numeroBits == 00){
                intBitSetAux = intBitSet;
                aux = intBitSet;
                intBitSet = 0;
                numeroBits = 16;
                intBitSet = (char)((char)Math.pow(2,numeroBits) - 1); // receber INT
                testInt = true;
            }
            aux = intBitSet;

        }
        return testInt;
    }
// Possui um auxiliar, portanto, ao final deve gravar o que está no auxiliar
// e não do principal 
    @Override
    public char getIntBitSet(){
        char retorno = intBitSetAux;
        intBitSetAux = 0;
        return retorno;
    }
// Ao final da codificação, deve zerar os bits que sobraram para não ficar lixo
// no arquivo codificado    
    public int getInt(){
        if (numeroBits!=0){
            for(int i=numeroBits-1; i>=0;i--){
               intBitSet -= (char)Math.pow(2,i);
            }
        }
        return intBitSet;
    }
}
